module arm.pwr;

/**
    电源相关寄存器
*/

import chip;

import arm.misc;

/// 判断 是否声明了 PWR 寄存器
private enum bool hasBusPeriph = HasPeriph!("PWR");
static if(hasBusPeriph):
import arm.bus;
import arm.rcc;


struct sPWR_CR
{
    uint LPDS:1;            /// 低功耗模式
    uint PDDS:1;            /// 低功耗模式
    uint CWUF:1;            /// 清除唤醒标志
    uint CSBF:1;            /// 清除停止模式标志
    uint PVDE:1;            /// 电源监视器
    uint PLS:3;             /// 电源监视器阈值
    uint DBP:1;             /// 调试模式
    uint FPDS:1;            /// 低功耗模式
    uint LPLVDS:1;          /// 低功耗模式
    uint MRLVDS:1;          /// 低功耗模式
    uint :1;                /// 保留
    uint ADCDC1:1;          /// ADCDC1
    uint VOS:2;             /// 电源监视器阈值
    ref T opCast(T:uint)() const
    {
        return *cast(T*)&this;
    }
}
debug static assert(sPWR_CR.sizeof == 4);

enum PLSFlag
{
    PLS_2_2 = 0b000,            /// 2.2V
    PLS_2_3 = 0b001,            /// 2.3V
    PLS_2_4 = 0b010,            /// 2.4V
    PLS_2_5 = 0b011,            /// 2.5V
    PLS_2_6 = 0b100,            /// 2.6V
    PLS_2_7 = 0b101,            /// 2.7V
    PLS_2_8 = 0b110,            /// 2.8V
    PLS_2_9 = 0b111,            /// 2.9V
}

enum VOSFlag
{
    Scale_4 = 0x00,             /// 2.1V
    Scale_3 = 0b01,            /// 2.2V
    Scale_2 = 0b10,            /// 2.3V
    Scale_1 = 0b11,             /// 2.4V
}

/**
* 供电控制
*/
static interface PWR //: MMIOBus!(Peripherals.PWR)
{
    enum PWR_Type* mBase = Peripherals.PWR;
    enum string IFName = "PWR";
    /// 电压设置
    pragma(inline,_inline)
    @property
    static void VoltageScale(VOSFlag scale)
    {
        mBase.CR.VOS = scale;
    }
    @property
    static VOSFlag VoltageScale()
    {
        return cast(VOSFlag)mBase.CR.VOS;

    }
    /// 初始化
    private
    pragma(crt_constructor,CrtPriority!(FlagCrt.ROOT,3))
    static this()
    {
        RCC.Power!(IFName~"EN")(1);
        //mBase.CR.VOS = VOSFlag.Scale_2;
        auto mCR = mBase.CR;
        mCR.VOS =0;
        mCR.VOS = VOSFlag.Scale_2;
        mBase.CR = mCR;
        /// 等待供电稳定
        /**
        todo:未知问题导致无法等待稳态
        */
        //while(!mBase.CSR.VOSRDY){}
        
    }
}


